<!--
 * @Author       : wfl
 * @LastEditors  : wfl
 * @description  :
 * @updateInfo   :pop
 * @Date         : 2023-07-24 09:35:10
 * @LastEditTime : 2023-12-14 18:27:23
-->
<script lang="ts" setup name="IkSvgIcon">
import { Icon } from '@iconify/vue'
import { ikStore } from 'iking-utils'
import type { PropType } from 'vue'
import parseSvgDataToObj from './parse-svg-to-obj'
import { ETableIconType, SYSTEM_ICON_TYPE } from '@/global/hooks/use-app'

const props = defineProps({
  name: {
    type: String,
    required: true
  },
  // 文字
  label: {
    type: String,
    default: ''
  },
  // svg大小
  size: {
    type: [String, Number] as PropType<'small' | 'default' | 'big' | number>,
    default: 'default'
  },
  // icon: 只显示图标 title: 只显示文字  all:显示图标+文字
  showType: {
    type: String as PropType<ETableIconType & any>,
    default: 'icon'
  },
  // 提示内容
  title: {
    type: String,
    default: ''
  },
  // 是否显示提示popper
  pop: {
    type: Boolean,
    default: false
  },
  // 旋转角度
  rotate: {
    type: Number,
    default: 0
  },
  // 显示背景色
  showBg: {
    type: Boolean,
    default: false
  },
  // 类型
  type: {
    type: [String, Number] as PropType<
      'primary' | 'info' | 'success' | 'warning' | 'danger' | number
    >,
    default: 'info'
  },
  // 背景色
  background: {
    type: String,
    default: ''
  },
  padding: {
    type: Number || null,
    default: null
  },
  // 第一个按钮是否需要margin-left   一般在表格行内操作时 第一个icon设置为false
  startMargin: {
    type: Boolean,
    default: true
  },
  disabled: {
    type: Boolean,
    default: false
  },
  // 宽度（已废弃）
  width: {
    type: Number,
    default: 40
  },
  //
  runtime: {
    type: Boolean,
    default: false
  },
  //
  flip: {
    type: String as () => 'horizontal' | 'vertical' | 'both' | '',
    default: ''
  },
  // 是否是表格内图标
  inTable: {
    type: Boolean,
    default: false
  }
})
const emit = defineEmits<{
  (event: 'click', e: any): void
}>()

const HAS_KEY = ikStore.local.has(ELocal.IK_SVG)
// 缓存定制化的svg文件
const iconObj: any = HAS_KEY
  ? ikStore.local.getItem(ELocal.IK_SVG)
  : parseSvgDataToObj((window as any)._iconfont_svg_string)
if (!HAS_KEY)
  ikStore.local.setItem(ELocal.IK_SVG, iconObj)

const suffix = import.meta.env.VITE_ICON_SUFFIX

const outputType = computed(() => {
  if (props.name?.includes('iksvg'))
    return 'svg'
  else if (props?.name?.indexOf('-') > 0 || props?.name?.indexOf(suffix) === 0)
    return props.runtime ? 'svg' : 'css'
  else if (props.name?.includes(':'))
    return 'svg'
  else return 'custom'
})

const outputName = computed(() => {
  if (props.name?.indexOf('i-') === 0) {
    let conversionName = props.name
    if (props.runtime)
      conversionName = conversionName.replace('i-', '')

    return conversionName
  }
  else {
    return props.name
  }
})

const transformStyle = computed(() => {
  const style = []
  if (props.flip !== '') {
    switch (props.flip) {
      case 'horizontal':
        style.push('rotateY(180deg)')
        break
      case 'vertical':
        style.push('rotateX(180deg)')
        break
      case 'both':
        style.push('rotateX(180deg)')
        style.push('rotateY(180deg)')
        break
    }
  }
  if (props.rotate !== 0)
    style.push(`rotate(${props.rotate % 360}deg)`)
  return `transform: ${style.join(' ')};`
})

const divStyle = computed(() =>
  props.showBg
    ? `background-color: ${
        props.type === 'primary' ? props.background : ''
      };padding: ${svgPadding.value};`
    : `padding: ${svgPadding.value};`
)

// !兼容旧版本
const oldIcon = computed(() => {
  if (iconObj[outputName.value]) {
    return iconObj[outputName.value]
  }
  else {
    const oldName = props.name?.replace('icon-', 'iksvg_')
    if (iconObj[oldName])
      return iconObj[oldName]
    else return ''
  }
})
const sysShowType = ([ETableIconType.文字图标, ETableIconType.文字].includes(SYSTEM_ICON_TYPE as any) && props.inTable)
const showLabel = computed(() => [ETableIconType.文字图标, ETableIconType.文字].includes(props.showType) || sysShowType)
const iconSize = computed(() =>
  ['big', 'default', 'small'].includes(props.size as string)
    ? props.size === 'big'
      ? 20
      : props.size === 'default'
        ? 16
        : 14
    : props.size
)

const svgPadding = ref('10px')
const setPadding = () => {
  if (props.padding !== null)
    svgPadding.value = `${props.padding}px`

  else if (typeof props.size === 'string' && props.size === 'big')
    svgPadding.value = '10px'
  else if (typeof props.size === 'number' && props.size >= 20)
    svgPadding.value = '10px'
  else
    svgPadding.value = '8px'
}
setPadding()
</script>

<template>
  <iksvg class="inline-flex">
    <template v-if="props.pop && !showLabel">
      <el-tooltip
        placement="top"
        title=""
        popper-class="ik-svg-icon-popover"
        trigger="hover"
        :enterable="false"
        :content="title"
      >
        <el-icon
          v-if="showType === 'icon'"
          :style="divStyle"
          class="ik-icon-btn"
          :size="iconSize"
          :class="[
            props.showBg ? 'show-bg' : null,
            type,
            disabled ? 'disabled' : null,
            startMargin ? 'start-margin' : null,
            `ik-${outputName}`,
          ]"
          v-bind="$attrs"
          @click="emit('click', $event)"
        >
          <svg
            v-if="oldIcon"
            :style="transformStyle"
            viewBox="0 0 1024 1024"
            v-html="oldIcon"
          />
          <i
            v-else-if="outputType === 'css'"
            :class="`${suffix} ${outputName} ${name?.split('-')[0]} ${
              name?.startsWith('ik') ? 'ik iksvg' : 'iconfont'
            }`"
            :style="`${transformStyle};fontSize:${iconSize}px;`"
          ></i>
          <Icon
            v-else-if="outputType === 'svg'"
            :icon="outputName"
            :style="transformStyle"
          />
          <svg v-else :style="transformStyle" aria-hidden="true">
            <use :xlink:href="`#icon-${outputName}`" />
          </svg>
        </el-icon>
        <el-button v-else-if="showType === ETableIconType.文字" text>
          {{
            label || title
          }}
        </el-button>
        <el-button v-else-if="showType === ETableIconType.文字图标">
          <template #icon>
            <el-icon
              :style="divStyle"
              class="ik-icon-btn"
              :size="iconSize"
              :class="[
                props.showBg ? 'show-bg' : null,
                type,
                disabled ? 'disabled' : null,
                startMargin ? 'start-margin' : null,
                `ik-${outputName}`,
              ]"
              v-bind="$attrs"
              @click="emit('click', $event)"
            >
              <svg
                v-if="oldIcon"
                :style="transformStyle"
                viewBox="0 0 1024 1024"
                v-html="oldIcon"
              />
              <i
                v-else-if="outputType === 'css'"
                :class="`${suffix} ${outputName} ${name?.split('-')[0]} ${
                  name?.startsWith('ik') ? 'ik iksvg' : 'iconfont'
                }`"
                :style="`${transformStyle};fontSize:${iconSize}px;`"
              ></i>
              <Icon
                v-else-if="outputType === 'svg'"
                :icon="outputName"
                :style="transformStyle"
              />
              <svg v-else :style="transformStyle" aria-hidden="true">
                <use :xlink:href="`#icon-${outputName}`" />
              </svg>
            </el-icon>
          </template>
          {{ label || title }}
        </el-button>
      </el-tooltip>
    </template>
    <template v-else>
      <el-icon
        v-if="(showType === ETableIconType.图标 && !inTable) || (SYSTEM_ICON_TYPE === ETableIconType.图标 && inTable)"
        :style="divStyle"
        class="ik-icon-btn"
        :size="iconSize"
        :class="[
          props.showBg ? 'show-bg' : null,
          type,
          disabled ? 'disabled' : null,
          startMargin ? 'start-margin' : null,
          `ik-${outputName}`,
        ]"
        v-bind="$attrs"
        @click="emit('click', $event)"
      >
        <svg
          v-if="oldIcon"
          :style="transformStyle"
          viewBox="0 0 1024 1024"
          v-html="oldIcon"
        />

        <i
          v-else-if="outputType === 'css'"
          :class="`${suffix} ${outputName} ${name?.split('-')[0]} ${
            name?.startsWith('ik') ? 'ik iksvg' : 'iconfont'
          }`"
          :style="`${transformStyle};fontSize:${iconSize}px;`"
        ></i>
        <Icon
          v-else-if="outputType === 'svg'"
          :icon="outputName"
          :style="transformStyle"
        />
        <svg v-else :style="transformStyle" aria-hidden="true">
          <use :xlink:href="`#icon-${outputName}`" />
        </svg>
      </el-icon>
      <el-button
        v-else-if="showType === ETableIconType.文字 || (SYSTEM_ICON_TYPE === ETableIconType.文字 && inTable)"
        :type="type === 'info' ? 'primary' : type"
        text
        @click="emit('click', $event)"
      >
        {{ label || title }}
      </el-button>
      <el-button
        v-else-if="showType === ETableIconType.文字图标"
        text
        :type="type === 'info' ? 'primary' : type"
        @click="emit('click', $event)"
      >
        <template #icon>
          <el-icon
            :style="divStyle"
            class="ik-icon-btn hover"
            :class="[type, `ik-${outputName}`]"
            v-bind="$attrs"
          >
            <svg
              v-if="oldIcon"
              :style="transformStyle"
              viewBox="0 0 1024 1024"
              v-html="oldIcon"
            />
            <i
              v-else-if="outputType === 'css'"
              :class="`${suffix} ${outputName} ${name?.split('-')[0]} ${
                name?.startsWith('ik') ? 'ik iksvg' : 'iconfont'
              }`"
              :style="`${transformStyle};fontSize:${iconSize}px;`"
            ></i>
            <Icon
              v-else-if="outputType === 'svg'"
              :icon="outputName"
              :style="transformStyle"
            />
            <svg v-else :style="transformStyle" aria-hidden="true">
              <use :xlink:href="`#icon-${outputName}`" />
            </svg>
          </el-icon>
        </template>
        {{ label || title }}
      </el-button>
    </template>
  </iksvg>
</template>

<style lang="scss" scoped>
.ik-icon-btn.disabled {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s;
  box-sizing: content-box;
}

.ik-icon-btn {
  box-sizing: content-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s;
  color: var(--ik-main-icon-deep-color);
  margin-right: 0;

  svg {
    path {
      transition: fill 0.3s;
    }
  }

  &.show-bg {
    border-radius: 6px;
    background-color: var(--ik-main-iconbg-bg);
    --ik-main-icon-deep-color: var(--ik-main-iconbg-deep-color);
    --ik-main-icon-color: var(--ik-main-iconbg-color);

    &.start-margin {
      margin-left: 10px;
    }

    & + i {
      margin-left: 10px;
    }

    &.default {
      svg {
        height: 50%;
        width: 50%;
      }
    }

    &.small {
      svg {
        height: 50%;
        width: 50%;
      }
    }
  }

  &.primary {
    --ik-main-icon-deep-color: var(--ik-theme-color);
    --ik-main-icon-color: var(--ik-theme-color-re);

    &:hover{
      --ik-main-icon-deep-color: var(--ik-theme-color);
      --ik-main-icon-color: var(--ik-theme-color-re);
    }
  }

  &:hover {
    --ik-main-icon-deep-color: var(--el-color-primary);
    --ik-main-icon-color: var(--ik-theme-color-re);
  }

  &.hover {
    --ik-main-icon-deep-color: var(--el-color-primary);
    --ik-main-icon-color: var(--ik-theme-color-re);
  }

  &.ik-icon-shanchu,
  &.ik-iksvg_shanchu1,
  &.ik-iksvg_shanchu {
    &:hover {
      --ik-main-icon-deep-color: var(--ik-main-icon-error-deep-color);
      --ik-main-icon-color: var(--ik-main-icon-error-color);
    }

    &.show-bg:hover {
      background-color: var(--ik-main-icon-error-bg);
    }
  }

  &.show-bg:hover {
    background-color: var(--ik-main-icon-active-color);
  }
}
</style>
